﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;
using ScrumTable.Config.ConfigManagement;
using ScrumTable.UI.View.Controls;
using ScrumTable.UI.View.CustomControl;
using ScrumTable.UI.View.Extension;
using ScrumTable.UI.View.Localization;
using ScrumTable.UI.View.Util;
using ScrumTable.UI.View.WinTouch.UserControls.Tool;
using ScrumTable.UI.View.WinTouch.UserControls.View;
using ScrumTable.UI.ViewModel;
using System.Linq;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.Common.Unity;
using ScrumTable.UI.ViewModel.Data;
using System.Windows.Shapes;
using ScrumTable.UI.ViewModel.Extension;

#endregion

namespace ScrumTable.UI.View.WinTouch.UserControls
{
    /// <summary>
    /// Shows a User Story as a Stack: Shows the User-Story and all childs (bugs)
    /// 
    /// </summary>
    public partial class StackedBugControl : ScrumUserControl, IDropUserControl
    {


        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------
        private ScrumState _bugState;
        private ScrumViewModelData _scrumData;
        private int _numbersOfOtherControls;

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------
        public ObservableCollection<BugViewModel> PlacedControls { get; set; }


        /// <summary>
        /// contains the number of other controls.
        /// </summary>
        public int NumbersOfOtherControls
        {
            get { return _numbersOfOtherControls; }
            set
            {
                _numbersOfOtherControls = value;
                MinWidth = StackedWidth;
            }
        }

        private double StackedWidth
        {
            get
            {
                var x = ViewElementUtils.FindVisualParent(typeof(ScreenGrid), this) as ScreenGrid;
                double parentWidth = (x != null) ? x.Width : ((AppScreen)Application.Current.MainWindow).BackGrid.Width;
                return (parentWidth - StackedDailyScrumStoryBoard.LengthFirstColumn) / NumbersOfOtherControls;
            }
        }
       
        /// <summary>
        /// DependencyProperty for UserStorie.
        /// </summary>
        public static readonly DependencyProperty IsExpanedProperty =
            DependencyProperty.Register("IsExpaned",
                                        typeof(bool),
                                        typeof(StackedBugControl),
                                        new UIPropertyMetadata(true, new PropertyChangedCallback(OnIsExpandedChanged)));

        /// <summary>
        /// Shows the control in a expaned mode, or not...
        /// </summary>
        /// <value></value>
        public bool IsExpaned
        {
            get { return (bool)GetValue(IsExpanedProperty); }
            set { SetValue(IsExpanedProperty, value); }
        }
       
 
       

        /// <summary>
        /// Shows all bugs of this state
        /// </summary>
        /// <value>The state of the story.</value>
        public ScrumState BugState
        {
            get
            {
                return _bugState;
            }
            set
            {
                _bugState = value;
                Init();
            }
        }
        #endregion


        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------


        /// <summary>
        /// Initializes a new instance of the <see cref="StackedUserStoryControl"/> class.
        /// </summary>
        public StackedBugControl()
        {
            PlacedControls = new ObservableCollection<BugViewModel>();
            _scrumData =  ((IAppScreen) Application.Current.MainWindow).Container.Resolve<ScrumViewModelData>();
            Loaded += OnBugControlLoaded;
            _scrumData.DataContext.ElementChanged += OnContextElementChanged;
            _scrumData.DataContext.CollectionChanged += OnContextCollectionChanged;
        }

       
      
        #endregion
        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        private static void OnIsExpandedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
           ((StackedBugControl)(sender)).Init();
        }

        private void Init()
        {
            if(Grid == null) { return; }
            Grid.Children.Clear();
            var bugs = (from x in _scrumData.CurrentIteration.Bugs where x.State == BugState && _scrumData.ContainsFilter(x) orderby x.Ranking descending select new BugViewModel(x)).ToList() ;

            if (IsExpaned)
            {
                ItemContainerControl.Visibility = Visibility.Visible;
                CreateChilds(bugs);
            }
            else
            {
                ItemContainerControl.Visibility = Visibility.Collapsed;
                CreateBugsChildsSmall(bugs);
            }
        }


        private void CreateBugsChildsSmall(IEnumerable<BugViewModel> bugs)
        {
            
            Grid grid = new Grid();
            StackPanel stackPanel = new StackPanel(){Orientation = Orientation.Horizontal};
            foreach (var bugViewModel in bugs)
            {
                stackPanel.Children.Add(
                    new Label()
                        {
                            Background = (Brush) Application.Current.Resources["IconBug"],
                            Content = bugViewModel.SeverityIndex,
                            Foreground = Brushes.Black,
                            FontWeight = FontWeights.Bold,
                            FontSize = 16,
                            HorizontalContentAlignment = HorizontalAlignment.Center,
                            VerticalContentAlignment = VerticalAlignment.Center,
                            HorizontalAlignment = HorizontalAlignment.Center,
                            VerticalAlignment = VerticalAlignment.Center,
                            Width = 24,
                            Height = 24,
                            Padding = new Thickness(0),
                        });
            }
            grid.Children.Add(stackPanel);
            Grid.Children.Add(grid);
            
        }

        private void CreateChilds(IList<BugViewModel> items)
        {
            PlacedControls.UnionToLeft(items);
        }

        /// <summary>
        /// Releases managed (c# or .net) resources.
        /// </summary>
        protected override void ReleaseManagedResources()
        {
            _scrumData.DataContext.CollectionChanged -= OnContextCollectionChanged;
            _scrumData.DataContext.ElementChanged -= OnContextElementChanged;
            base.ReleaseManagedResources();
            
        }


        private void CollectionChanged(DomainCollectionChangedEventArgs childEvent)
        {
            if (childEvent.Owner == _scrumData.CurrentIteration.Bugs)
            {
                Init();
            }
        }

        private void BringItemToFront(object sender)
        {
            var cont = ViewElementUtils.FindVisualChild<WrapPanelAnimated>(ItemContainerControl);
            var uiElement = (FrameworkElement)sender;

            foreach (FrameworkElement children in cont.Children)
            {
                Grid.SetZIndex(children, 0);
                if (children.DataContext == uiElement.DataContext)
                {
                    children.SetValue(Canvas.ZIndexProperty, 999);
                }
            }
        }



        #endregion

        #region events

        private void OnBugControlLoaded(object sender, RoutedEventArgs e)
        {
            InitializeComponent();
            ItemContainerControl.Width = ActualWidth;
            Loaded -= OnBugControlLoaded;
            Init();
        }


        private void OnDrop(object sender, Microsoft.Surface.Presentation.SurfaceDragDropEventArgs e)
        {
            if (CanDrop(e.Cursor.Data)==CanDropResult.CanDrop)
            {
                var bug = (BugViewModel) e.Cursor.Data;
                using (bug.Original.Context.UndoManager.CaptureUndoRedoAction(bug.Name))
                {
                    ((BugViewModel)e.Cursor.Data).State = BugState;

                    if (_scrumData.CurrentIteration.Id != ((BugViewModel)e.Cursor.Data).Original.Parent.Id)
                    {
                        ((IAppScreen)Application.Current.MainWindow).Container.Resolve<ScrumViewModelData>().CurrentIteration.Bugs.Add(((BugViewModel)e.Cursor.Data).Original);
                    }
                }

            }
            e.Effects = DragDropEffects.None;
        }
        
        private void OnContextElementChanged(object sender, PropertyChangedEventArgs e)
        {
            var args = e as DomainChangedEventArgs;
            if (args == null) return;

            if (args.ContainsElementId(_scrumData.CurrentIteration.Id, true))
            {
                if (e is DomainChangedEventArgs && ((DomainChangedEventArgs)e).ContainsPropertyNames("State", "Priority", "Severity"))
                {
                    Init();
                }
            }
        }


        private void OnContextCollectionChanged(object sender, DomainCollectionChangedEventArgs e)
        {
            if (e is MultipleDomainCollectionChangedEventArgs)
            {
                MultipleDomainCollectionChangedEventArgs args = (MultipleDomainCollectionChangedEventArgs)e;
                foreach (var childEvent in args.Children)
                {
                    CollectionChanged(childEvent);
                }
            }
            else
            {
                CollectionChanged(e);
            }
        }

        private void OnItemControlTouchDown(object sender, System.Windows.Input.TouchEventArgs e)
        {
            e.Handled = true;
        }

        private void OnItemControlMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

        private void OnItemPreviewDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            BringItemToFront(sender);
        }


        private void OnItemPreviewDown(object sender, System.Windows.Input.TouchEventArgs e)
        {
            BringItemToFront(sender);
        }

        #endregion


        #region IDropUserControl Members

        public FrameworkElement GetRootControl
        {
            get { return this; }
        }

        public bool ShowIconWithbackground
        {
            get { return true; }
        }

        public CanDropResult CanDrop(object objectToDrop)
        {
            return  BugViewModel.CanChangeState(objectToDrop, BugState);
        }

        #endregion

    }
}
